package com.mccken.practice;

import java.lang.reflect.Field;
import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.locks.LockSupport;

import sun.misc.Unsafe;

/**
 * @program: mccken-collect
 * @description:
 * @author: mccken
 * @create: 2023-12-06 15:41
 **/
public class MyLock02 {


	// step1 定义一个状态量status: 1表示锁被持有，0表示锁未被持有
	private volatile int status = 0;

	private static final Queue<Thread> QUEUE = new LinkedBlockingQueue<>();

	public boolean lock() {
		while (!compareAndSet(0,1)) {
			QUEUE.offer(Thread.currentThread());
			LockSupport.park();//线程休眠
		}
		return true;
	}

	public void unlock() {
		status = 0;
		LockSupport.unpark(QUEUE.poll());
	}


	private static final long valueOffset;
	private static final Unsafe unsafe = reflectGetUnsafe();

	static {
		try {
			valueOffset = unsafe.objectFieldOffset(MyLock01.class.getDeclaredField("status"));
		} catch (NoSuchFieldException e) {
			throw new RuntimeException(e);
		}
	}

	private static Unsafe reflectGetUnsafe() {
		try {
			Field field = Unsafe.class.getDeclaredField("theUnsafe");
			field.setAccessible(true);
			return (Unsafe) field.get(null);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	private boolean compareAndSet(int expect, int update) {
		return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
	}
}
